//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.example.bootintegration.configuration;

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerFactory;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.SerializerFactory;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.databind.ser.std.MapProperty;
import com.fasterxml.jackson.databind.type.MapType;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.util.List;
import java.util.stream.Collectors;

class SensitiveModifierFactoryBean extends AbstractFactoryBean<ObjectMapper> {
    private final Jackson2ObjectMapperBuilder builder;

    public SensitiveModifierFactoryBean(Jackson2ObjectMapperBuilder builder) {
        this.builder = builder;
    }

    public Class<ObjectMapper> getObjectType() {
        return ObjectMapper.class;
    }

    protected ObjectMapper createInstance() {
        SerializerFactory sf = BeanSerializerFactory.instance.withSerializerModifier(new SensitiveBeanSerializerModifier());
        SilentSimpleFilterProvider silentFilterProvider = new SilentSimpleFilterProvider();
        silentFilterProvider.addFilter(SensitiveMapPropertyFilter.class.getSimpleName(), new SensitiveMapPropertyFilter());
        ObjectMapper mapper = this.builder.createXmlMapper(false).build();
        return mapper.setSerializerFactory(sf).setFilterProvider(silentFilterProvider).setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker().withFieldVisibility(Visibility.ANY).withGetterVisibility(Visibility.NONE).withIsGetterVisibility(Visibility.NONE).withSetterVisibility(Visibility.NONE).withCreatorVisibility(Visibility.NONE));
    }

    static class SilentSimpleFilterProvider extends SimpleFilterProvider {
        SilentSimpleFilterProvider() {
        }

        public PropertyFilter findPropertyFilter(Object filterId, Object valueToFilter) {
            return (PropertyFilter)super._filtersById.get(filterId);
        }
    }

    static class SensitiveMapPropertyFilter extends SimpleBeanPropertyFilter {
        SensitiveMapPropertyFilter() {
        }

        public void serializeAsField(Object pojo, JsonGenerator gen, SerializerProvider prov, PropertyWriter writer) throws Exception {
            MapProperty mapWriter = (MapProperty)writer;
            Object value = mapWriter.getValue();
            if (value instanceof String) {
                String altValue = "altValue";
                mapWriter.setValue(altValue);
            }

            super.serializeAsField(pojo, gen, prov, writer);
        }
    }

    static class SensitiveBeanPropertyWriter extends BeanPropertyWriter {
        private static final long serialVersionUID = -8954928101186700392L;
        private final BeanPropertyWriter delegate;

        public SensitiveBeanPropertyWriter(BeanPropertyWriter delegate) {
            super(delegate);
            this.delegate = delegate;
        }

        public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {

        }
    }

    static class SensitiveBeanSerializerModifier extends BeanSerializerModifier {
        SensitiveBeanSerializerModifier() {
        }

        public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> writers) {
            return (List)writers.stream().map(SensitiveBeanPropertyWriter::new).collect(Collectors.toList());
        }

        public JsonSerializer<?> modifyMapSerializer(SerializationConfig config, MapType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer) {
            return serializer.withFilterId(SensitiveMapPropertyFilter.class.getSimpleName());
        }
    }
}
